<script setup lang="ts">
import { reactive, ref, shallowReactive, watch, useTemplateRef } from "vue"
import * as types from "../types"
import { Methods } from "../enums"
const emit = defineEmits(['rename'])
const props = defineModel<types.methodWithUrl>({ required: true })
const refs = [useTemplateRef('input1'), useTemplateRef('input2'), useTemplateRef('input3'), useTemplateRef('input4')]
const defaultInfo: types.editMethod = { method: 'GET', path: '', func: '', desc: '' }
const info = ref<types.editMethod>(structuredClone(defaultInfo))
//innerStatus -1 代表不存在 0 代表对象 1 代表字符串
const innerStatus = reactive<{ queryVar: number, bodyVar: number, response: number }>({ queryVar: -1, bodyVar: -1, response: -1 })
const innerObj = shallowReactive<{ queryVar: types.model, bodyVar: types.model, response: types.model }>({ queryVar: {}, bodyVar: {}, response: {} })
function checkName(): { from: string, to: string } | null {
    for (const element of refs) {
        element.value?.update()
    }
    if (innerStatus.bodyVar != -1) {
        info.value.bodyVar = innerObj.bodyVar
    }
    if (innerStatus.queryVar != -1) {
        info.value.queryVar = innerObj.queryVar
    }
    if (innerStatus.response != -1) {
        info.value.response = innerObj.response
    }
    let t = props.value
    let url = `${info.value.method} ${info.value.path}`
    let ret: { from: string, to: string } | null = null
    ret = (url != t.url) ? { from: t.url, to: url } : null
    t.url = url
    t.method.desc = info.value.desc
    t.method.func = info.value.func
    if (info.value.auth == '') {
        delete t.method.auth
    } else {
        t.method.auth = info.value.auth
    }
    if (info.value.bodyVar) {
        t.method.bodyVar = info.value.bodyVar
    } else {
        delete t.method.bodyVar
    }
    if (info.value.queryVar) {
        t.method.queryVar = info.value.queryVar
    } else {
        delete t.method.queryVar
    }
    if (info.value.response) {
        t.method.response = info.value.response
    } else {
        delete t.method.response
    }
    if (info.value.pathVar) {
        t.method.pathVar = info.value.pathVar
    } else {
        delete t.method.pathVar
    }
    props.value = t
    return ret
}
defineExpose({
    checkName
})
watch(() => props.value.url, () => {
    let url = props.value.url.split(' ')
    info.value = structuredClone(defaultInfo)
    info.value.method = url[0] as any
    info.value.path = url[1]
    info.value.desc = props.value.method.desc
    info.value.func = props.value.method.func
    info.value.auth = props.value.method.auth || ''
    if (props.value.method.bodyVar) {
        info.value.bodyVar = props.value.method.bodyVar
        innerStatus.bodyVar = typeof props.value.method.bodyVar === 'object' ? 0 : 1
        if (innerStatus.bodyVar == 0) {
            innerObj.bodyVar = props.value.method.bodyVar as types.model
        }
    } else {
        innerStatus.bodyVar = -1
    }
    if (props.value.method.queryVar) {
        info.value.queryVar = props.value.method.queryVar
        innerObj.queryVar = props.value.method.queryVar as types.model
        innerStatus.queryVar = 0
    } else {
        innerStatus.queryVar = -1
    }
    if (props.value.method.pathVar) {
        info.value.pathVar = props.value.method.pathVar
    } else {
        delete info.value.pathVar
    }
    if (props.value.method.response) {
        info.value.response = props.value.method.response
        innerStatus.response = typeof props.value.method.response === 'object' ? 0 : 1
        if (innerStatus.response == 0) {
            innerObj.response = props.value.method.response as types.model
        }
    } else {
        innerStatus.response = -1
    }
}, { immediate: true })
const patten = /\{(.*?)\}/g
watch(() => info.value.path, (val) => {
    const match = val.match(patten)
    const res = match?.map(x => x.slice(1, -1)) || []
    if (info.value.pathVar) {
        Object.keys(info.value.pathVar).forEach(key => {
            if (!res.includes(key)) {
                delete info.value.pathVar![key]
            }
        })
    }
    if (res.length > 0) {
        res.forEach(key => {
            if (!info.value.pathVar) {
                info.value.pathVar = {}
            }
            if (!info.value.pathVar![key]) {
                info.value.pathVar![key] = 'string'
            }
        })
    } else if (info.value.pathVar) {
        delete info.value.pathVar
    }
})
function switchBody(checked: any) {
    innerStatus.bodyVar = checked ? 0 : 1
    if (checked) {
        info.value.bodyVar = {}
    } else {
        info.value.bodyVar = '-'
    }
}
function switchRes(checked: any) {
    innerStatus.response = checked ? 0 : 1
    if (checked) {
        info.value.response = {}
    } else {
        info.value.response = '-'
    }
}
function addVar(type: Number) {
    if (type == 0) {
        info.value.bodyVar = {}
        innerStatus.bodyVar = 0
    } else if (type == 1) {
        info.value.queryVar = {}
        innerStatus.queryVar = 0
    } else if (type == 2) {
        info.value.response = {}
        innerStatus.response = 0
    }
}
</script>
<template>
    <a-form autocomplete="off">
        <a-input-group compact>
            <a-select v-model:value="info.method" style="width: 20%">
                <a-select-option v-for="x in Methods" :value="x">{{ x }}</a-select-option>
            </a-select>
            <a-input v-model:value.lazy="info.path" style="width: 75%" />
        </a-input-group>
        <a-form-item label="注释">
            <a-input v-model:value="info.desc" />
        </a-form-item>
        <a-form-item label="认证类型">
            <a-select v-model:value="info.auth">
                <a-select-option value="main">main</a-select-option>
                <a-select-option value="main_unforce">main_unforce</a-select-option>
                <a-select-option value="">无</a-select-option>
            </a-select>
        </a-form-item>
        <a-form-item label="代码方法名">
            <a-input v-model:value="info.func" />
        </a-form-item>
        <div v-if="info.queryVar">
            <h3>queryVar</h3>
            <ModelObj v-model="innerObj.queryVar as types.model" ref="input1" />
        </div>
        <a-button type="primary" v-else @click="addVar(1)">添加queryVar</a-button>
        <br>
        <div v-if="info.bodyVar">
            <h3>bodyVar</h3>
            <a-form-item label="类型属性">
                <a-switch v-model:checked="innerStatus.bodyVar" @change="switchBody" checked-children="对象"
                    un-checked-children="引用" />
            </a-form-item>
            <ModelObj v-if="innerStatus.bodyVar == 0" v-model="innerObj.bodyVar as types.model" ref="input2" />
            <ModelRef v-else v-model="info.bodyVar as string" />
        </div>
        <a-button type="primary" v-else @click="addVar(0)">添加body</a-button>
        <div v-if="info.pathVar">
            <h3>pathVar</h3>
            <ModelObj v-model="info.pathVar" readonly ref="input3" />
        </div>
        <br>
        <div v-if="info.response">
            <h3>返回结果</h3>
            <a-form-item label="类型属性">
                <a-switch v-model:checked="innerStatus.response" @change="switchRes" checked-children="对象"
                    un-checked-children="引用" />
            </a-form-item>
            <ModelObj v-if="innerStatus.response == 0" v-model="innerObj.response as types.model" ref="input4" />
            <ModelRef v-else v-model="info.response as string" />
        </div>
        <a-button type="primary" v-else @click="addVar(2)">添加响应</a-button>
    </a-form>
</template>
<style></style>